{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Plotting Colormaps\n",
    "\n",
    "You can use colormaps to colour your network plots in order to get a quick and simple overview of line loadings and bus voltages. The plotting module provides functions to easily modify your bus and line collections. It also provides colourbars to match the colourcodes to the according numerical values."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Continuous Colormaps\n",
    "\n",
    "First, we load the network and run a loadflow to retrieve results:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T09:20:37.592372Z",
     "start_time": "2025-10-20T09:20:34.172168Z"
    }
   },
   "outputs": [],
   "source": [
    "from pandapower.networks import mv_oberrhein\n",
    "from pandapower.run import runpp\n",
    "from pandapower.plotting import cmap_continuous, create_line_collection, draw_collections, create_bus_collection, cmap_discrete, cmap_logarithmic"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T09:20:40.825540Z",
     "start_time": "2025-10-20T09:20:37.598367Z"
    }
   },
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "\n",
    "net = mv_oberrhein()\n",
    "runpp(net)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The pandapower plotting package contains convenience functions to create common colorbars and norms. We use the cmap_continuous function to get a linear colormap with color centers green at 20%, yellow at 50% and red at 60% line loading:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T09:20:40.841541Z",
     "start_time": "2025-10-20T09:20:40.830547Z"
    }
   },
   "outputs": [],
   "source": [
    "cmap_list=[(20, \"green\"), (50, \"yellow\"), (60, \"red\")]\n",
    "cmap, norm = cmap_continuous(cmap_list)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The colormap and norm are now passend to the create_bus_collection function and the collection is plotted with draw_collections:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T09:20:40.981105Z",
     "start_time": "2025-10-20T09:20:40.845547Z"
    }
   },
   "outputs": [],
   "source": [
    "lc = create_line_collection(net, net.line.index, zorder=1, cmap=cmap, norm=norm, linewidths=2)\n",
    "draw_collections([lc], figsize=(8,6))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T09:20:41.215375Z",
     "start_time": "2025-10-20T09:20:40.987647Z"
    }
   },
   "outputs": [],
   "source": [
    "cmap_list=[(0.975, \"blue\"), (1.0, \"green\"), (1.03, \"red\")]\n",
    "cmap, norm = cmap_continuous(cmap_list)\n",
    "bc = create_bus_collection(net, net.bus.index, size=80, zorder=2, cmap=cmap, norm=norm)\n",
    "draw_collections([lc, bc], figsize=(8,6))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Discrete Colormaps\n",
    "\n",
    "Discrete colormaps can be used in the same way as continuous colormaps using the cmap_voltage_discrete and cmap_loading_discrete functions. For discrete colormaps, each color has to be assigned a range instead of a center:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T09:20:42.190254Z",
     "start_time": "2025-10-20T09:20:41.218371Z"
    }
   },
   "outputs": [],
   "source": [
    "net = mv_oberrhein()\n",
    "runpp(net)\n",
    "cmap_list=[((0.975, 0.985), \"blue\"), ((0.985, 1.0), \"green\"), ((1.0, 1.03), \"red\")]\n",
    "cmap, norm = cmap_discrete(cmap_list)\n",
    "bc = create_bus_collection(net, net.bus.index, size=80, zorder=2, cmap=cmap, norm=norm)\n",
    "\n",
    "cmap_list=[((10, 40), \"green\"), ((40, 55), \"yellow\"), ((55, 60), \"red\")]\n",
    "cmap, norm = cmap_discrete(cmap_list)\n",
    "lc = create_line_collection(net, net.line.index, zorder=1, cmap=cmap, norm=norm, linewidths=2)\n",
    "draw_collections([lc, bc], figsize=(8,6))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Logarithmic Colormaps"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This option can be used to create logarithmic colormaps. The intermediate values of the logarithmic scale are created automatically based on the minimum an maximum given values in analogy to the LogNorm. The colormap itself has a linear segmentation of the given colors. Also, it can only be used with at least 3 colors an increasing values which have to be above 0. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T09:20:43.569184Z",
     "start_time": "2025-10-20T09:20:42.197251Z"
    }
   },
   "outputs": [],
   "source": [
    "net = mv_oberrhein()\n",
    "runpp(net)\n",
    "\n",
    "min_value = 1.0\n",
    "max_value = 1.03\n",
    "colors = [\"blue\", \"green\", \"red\"]\n",
    "cmap, norm = cmap_logarithmic(min_value, max_value, colors)\n",
    "bc = create_bus_collection(net, size=100, cmap=cmap, norm=norm, zorder=2)\n",
    "\n",
    "min_value = 10\n",
    "max_value = 60\n",
    "colors = [\"green\", \"yellow\", \"red\"]\n",
    "cmap, norm = cmap_logarithmic(min_value, max_value, colors)\n",
    "lc = create_line_collection(net, net.line.index, zorder=1, cmap=cmap, norm=norm, linewidth=2)\n",
    "\n",
    "draw_collections([bc, lc])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Custom Colormaps and Colorbars\n",
    "\n",
    "The functions to create colormaps and norms are merely convenience functions. You can individually create any colormap you like and pass it to the create_collection functions.\n",
    "\n",
    "For example, for the colorbar \"PuBu_r\" from matplotlib:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T09:20:43.770283Z",
     "start_time": "2025-10-20T09:20:43.577221Z"
    }
   },
   "outputs": [],
   "source": [
    "from matplotlib.pyplot import get_cmap\n",
    "from matplotlib.colors import Normalize\n",
    "\n",
    "cmap = get_cmap('PuBu_r')\n",
    "lc = create_line_collection(net, net.line.index, zorder=1, color=\"grey\", linewidths=2,\n",
    "                                     cmap=cmap)\n",
    "bc = create_bus_collection(net, net.bus.index, size=80, zorder=2)\n",
    "draw_collections([lc, bc], figsize=(8,6))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Plotting without a norm maps the colorbar to the range of the data points (here: line loadings). Normalizing to values between 20 and 100 yields:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T09:20:43.991757Z",
     "start_time": "2025-10-20T09:20:43.776290Z"
    }
   },
   "outputs": [],
   "source": [
    "cmap = get_cmap('PuBu_r')\n",
    "norm = Normalize(vmin=20, vmax=100)\n",
    "lc = create_line_collection(net, net.line.index, zorder=1, color=\"grey\", linewidths=2,\n",
    "                                     cmap=cmap, norm=norm)\n",
    "bc = create_bus_collection(net, net.bus.index, size=80, zorder=2)\n",
    "draw_collections([lc, bc], figsize=(8,6))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The colorbar can be customized by disabling the automatic plotting of the colorbar in draw_collections and plotting the colorbar directly with the desired parameters:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-10-20T09:20:44.183104Z",
     "start_time": "2025-10-20T09:20:43.997911Z"
    }
   },
   "outputs": [],
   "source": [
    "from matplotlib.pyplot import colorbar\n",
    "\n",
    "ax = draw_collections([lc, bc], figsize=(8,6), plot_colorbars=False)\n",
    "cbar = colorbar(lc, ax=ax, extend=\"max\")\n",
    "cbar.set_ticks([50, 70, 100])\n",
    "cbar.ax.set_ylabel(\"This is a individual colorbar title\")"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
